package com.task.scheduler.handler;

import com.task.scheduler.event.TaskEvent;
import com.task.scheduler.enums.TaskStatus;
import com.task.scheduler.model.GenericTask;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

/**
 * 任务事件处理器注册中心
 * 支持根据 taskType 注册成功/失败回调
 *
 * 使用方式：
 * 在用户模块中注入该类并调用 onSuccess/onFailure 方法注册回调。
 */
@Component
public class TaskEventHandlerRegistrar implements ApplicationListener<TaskEvent> {

    // 成功回调映射：taskType -> handler
    private final Map<String, BiConsumer<GenericTask, String>> successHandlers = new HashMap<>();

    // 失败回调映射：taskType -> handler
    private final Map<String, BiConsumer<GenericTask, Exception>> failureHandlers = new HashMap<>();

    @Override
    public void onApplicationEvent(TaskEvent event) {
        String taskType = event.getTask().getTaskType();
        GenericTask task = event.getTask();

        if (event.getStatus() == TaskStatus.SUCCESS && event.getResult() != null) {
            BiConsumer<GenericTask, String> handler = successHandlers.get(taskType);
            if (task.getOnSuccess() == null && handler != null) {
                handler.accept(task, event.getResult());
            }
        } else if (event.getStatus() == TaskStatus.FAILED) {
            BiConsumer<GenericTask, Exception> handler = failureHandlers.get(taskType);
            if (task.getOnFailure() == null && handler != null) {
                handler.accept(task, new RuntimeException("任务执行失败: " + event.getResult()));
            }
        }
    }

    /**
     * 注册指定 taskType 的成功回调
     * @param taskType 任务类型（如 HTTP / SHELL）
     * @param handler 回调函数，接收任务对象和执行结果
     */
    public void onSuccess(String taskType, BiConsumer<GenericTask, String> handler) {
        successHandlers.put(taskType, handler);
    }

    /**
     * 注册指定 taskType 的失败回调
     * @param taskType 任务类型（如 HTTP / SHELL）
     * @param handler 回调函数，接收任务对象和异常信息
     */
    public void onFailure(String taskType, BiConsumer<GenericTask, Exception> handler) {
        failureHandlers.put(taskType, handler);
    }
}
